import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


public class ParserThread extends Thread
{
	MultiThreadEnv my_delegate;
	private boolean still_retrieving = true;
	public void run()
	{
		while (still_retrieving)
		{
			PageObject parse_doc 	= null;
			boolean parse_increased = false;
			try
			{
				my_delegate.document_lock.lock();//CS
					parse_doc = my_delegate.getWebDocuments().poll();
				my_delegate.document_lock.unlock();//END CS
				
				if (parse_doc != null)
				{	
					long starttime = System.currentTimeMillis();
					int url_count = 0;
					Elements links 		= parse_doc.getDocument().select("a");
					for (int i = 0; i < links.size(); i++)
					{
						Element element = links.get(i);
						String abshref 	= element.attr("abs:href");
						url_count++;
						my_delegate.web_lock.lock();//CS
						if (!(my_delegate.haveVisitedPage(abshref)) && my_delegate.getWebPages().size() <= my_delegate.getParsePageLimit())
						{
							my_delegate.savePageAsVisited(abshref);
							my_delegate.getWebPages().add(abshref);	
						}
							if (!parse_increased)
							{
								if (my_delegate.parsed_pages >= my_delegate.getParsePageLimit()){my_delegate.web_lock.unlock();still_retrieving = false;return;}
								parse_doc.setPageNumber(my_delegate.parsed_pages);
								my_delegate.parsed_pages++;	
								parse_increased = true;
							}
						my_delegate.web_lock.unlock();//END CS
					}
					
					int word_count 							= 0;
					String html_elements 					= parse_doc.getDocument().text();
					StringTokenizer tokenizer 				= new StringTokenizer(html_elements, " ,./\'\\=!@#$%^&*()\":;");
					HashMap<Integer, Integer> found_words 	= new HashMap<Integer, Integer>();
					ArrayList<String> word_array 			= new ArrayList<String>();
					
					while(tokenizer.hasMoreElements())
					{
						word_array.add(tokenizer.nextToken().trim().toLowerCase());
					}
					for (int i = 0; i < word_array.size(); i++)
					{
						Integer hashcode_value = found_words.get(word_array.get(i).toString().toLowerCase().hashCode());
						if(hashcode_value != null)
						{
							found_words.put(word_array.get(i).toString().toLowerCase().hashCode(), found_words.get(word_array.get(i).toString().toLowerCase().hashCode()).intValue() + 1);	
						}
						else
						{
							found_words.put(word_array.get(i).toString().toLowerCase().hashCode(), 1);
						}
						word_count++;
					}
					my_delegate.analyzer_lock.lock();//CS Note order matters in this CS
						parse_doc.setHashMap(found_words);
						
						//This will increase the key words count for this page.
						for (int i = 0; i < my_delegate.my_keyword_array.size(); i++)
						{
							if (found_words.get(my_delegate.my_keyword_array.get(i).hashCode()) != null){
								
								my_delegate.my_keyword_map.put(my_delegate.my_keyword_array.get(i).hashCode(), 
										my_delegate.my_keyword_map.get(my_delegate.my_keyword_array.get(i).hashCode()) + 
										found_words.get(my_delegate.my_keyword_array.get(i).hashCode()));
							}
						}
						
						long endtime = System.currentTimeMillis();
						my_delegate.setTotalParseTime(my_delegate.getTotalParseTme() + (endtime - starttime));
						parse_doc.setAverageParseTime(my_delegate.getTotalParseTme());
						parse_doc.setRunningTime(System.currentTimeMillis() - my_delegate.starttime);
						parse_doc.setKeywordArray(my_delegate.my_keyword_array);
						parse_doc.setKeywordMap(my_delegate.my_keyword_map);
					
						my_delegate.setTotalFoundURLs(my_delegate.getTotalFoundURLs() + url_count);
						parse_doc.setTotalReadURLCount(my_delegate.getTotalFoundURLs());
					
						my_delegate.setTotalWordsParsed(my_delegate.getTotalWordsParse() + word_count);
						parse_doc.setTotalWordsAtReadTime(my_delegate.getTotalWordsParse());
						
						my_delegate.getHashArrayQueue().add(parse_doc);
						
					my_delegate.analyzer_lock.unlock();//END CS
				}
			}
			catch (Exception the_e)
			{
				if (parse_doc != null)
				{
					System.out.println("Could not parse url: " + parse_doc.getUrl() + the_e.getMessage());	
				}
			}
		}
	}
	public void setDelegate(MultiThreadEnv the_delegate)
	{
		my_delegate 	= the_delegate;
	}
	public void killRetrieve()
	{
		still_retrieving = false;
	}
}
